﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

using Sintaxe;
using Sintaxe.Simbolos;
using Sintaxe.Tokens;
using Sintaxe.Instrucoes;

/*
 * 
 * Representa uma instrução da maquina do processador XYSC_1
 * 
 * Diretivas etc. podem ser tratadas com o mesmo formulário que trata estas instruções.
 * O Interface IInstrucao permite substituir a uma para outra onde for necessário.
 */

namespace XYSC_1
{
    public class IM_XYSC1_V2 : Instrucao
    {
        // Constructor
        //
        public IM_XYSC1_V2() : base() { }

        public IM_XYSC1_V2(BinaryReader brFonte)
            : base(brFonte)
        {
            RegDest = brFonte.ReadString();
            RegFont = brFonte.ReadString();
            Condicao = brFonte.ReadString();
        }


        public override void Gravar(BinaryWriter bwFonte)
        {
            base.Gravar(bwFonte);
            bwFonte.Write(RegDest);
            bwFonte.Write(RegFont);
            bwFonte.Write(Condicao);
        }

        // Os campos da instrução/diretiva ===============
        //
        public string RegDest = "";
        public string RegFont = "";
        public string Condicao = "";

        // Membros para processamento de endereços, rótulos etc.
        //
        //public Fixup FixupAtual;   // relocação é executado em varios passos, resultados intermediaios "moram" aqui

        // Métodos de acesso/manipulação, herdados do IInstrução
        //

        // Métodos de transformação em uma representação
        //

        public override string RepVisual(IProcessador prmProc)
        {
            // A representação depende da operação, porque Cat == 'C' e operacao != "".
            string ss;
            string RotLin;
            string strCom = "";
            string FmtAtual = "";
            XYSC1_V2 PROC = (XYSC1_V2) prmProc;

            // temos um rótulo?
            if ((Rotulo == null) | (Rotulo == "")) RotLin = "          "; // 10 espacos
            else RotLin = String.Format("{0, -8} :", Rotulo);

            // salao de beleza para o comentário
            if ((Comentario != null) & (Comentario != ""))
            {
                if (Comentario.Substring(0, 2) != "//") strCom = "//";
                strCom += Comentario;
            }

            // criar representacao baseado em Format
            Mnemo mm = (Mnemo)PROC._Mnemos.Item(Operacao);
            //Mnemo mm = (Diretiva)Diretor.Diretivas.Item(Operacao);

            if (mm == null) return (String.Format("Erro. Mnemo {0} desconhecida", Operacao));

            FmtAtual = mm.fmtVisu;
            ss = String.Format(FmtAtual, RotLin,
                                         Operacao,
                                         RegDest,
                                         RegFont,
                                         Condicao,
                                         Imediato,
                                         strCom);
            return ss;
        }

        // Métodos de suporte para relocaçaõ
        //
        public UInt64 EndMax()
        {
            return (1 << 16);
        }


        // Transformar instrução em representação binária
        // estas rotinas ficam aqui para terem acesso aos membros da instrução
        //


    }
}
